package com.module.lemlin.http

import com.blankj.utilcode.util.LogUtils
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.core.ObservableTransformer
import io.reactivex.rxjava3.disposables.Disposable
import io.reactivex.rxjava3.schedulers.Schedulers
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.asRequestBody
import rxhttp.wrapper.annotation.DefaultDomain
import java.io.File
import java.lang.Exception
import java.lang.reflect.InvocationHandler
import java.lang.reflect.Method
import java.lang.reflect.Proxy


@DefaultDomain
const val baseUrl = "http://www.51bbxwj.com"

abstract class HttpServiceRxHttpManager<ApiService : HttpServiceRxHttpApi>(apiServiceClass: Class<ApiService>) {

    protected val apiRxHttpService: ApiService by lazy {
        //apiServiceClass.newInstance()
//        apiServiceClass.interfaces[0] as ApiService
        apiServiceClass.genericInterfaces.forEach {
            LogUtils.e("=============${it}")
        }
        try {
            val ss = (Proxy.newProxyInstance(apiServiceClass.classLoader, apiServiceClass.interfaces,object :InvocationHandler{
                override fun invoke(proxy: Any?, method: Method, args: Array<out Any>?): Any {
//                    LogUtils.e("==${proxy}=======${args?.get(0)}")
                    val any = method.invoke(this,args)
                    return any
                }
            }) as ApiService)
            LogUtils.e("====${ss}")
            return@lazy ss

        } catch (e:Exception) {
            LogUtils.e("=====${e.message}")
            throw Exception(e)
        }
    }
}

abstract class HttpServiceRetrofitManager<ApiService : HttpServiceRetrofitApi>(apiServiceClass: Class<ApiService>) {

    protected val apiRetrofitService: ApiService by lazy {
        HttpServiceFactory.create(apiServiceClass, "")
    }

    fun upload(url: String, file: File, listener: ProgressListener? = null) {
        val requestBody: RequestBody =
            file.asRequestBody("multipart/form-data".toMediaTypeOrNull())
        val multipartBody: MultipartBody.Part =
            MultipartBody.Part.createFormData(
                name = "aFile", file.name, ProgressRequestBody(requestBody, listener)
            )
        apiRetrofitService.upload(url, requestBody, multipartBody)
            .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
            .subscribe()
    }

}

/**
 * 在子线程加载数据
 */
private fun <Response> observeOnMain(): ObservableTransformer<Response, Response> {
    return ObservableTransformer { upstream: Observable<Response> ->
        upstream.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
    }
}

/**
 * 网络加载数据观察
 */
fun <data> subscribe1(
    observable: Observable<data>,
    listener: SubscribeViewModel<data>
): Disposable = observable.compose(observeOnMain<data>())
    .doOnSubscribe {
        listener.onStart()
    }.doOnError {
        if (it.code == 401) {

        }
    }.subscribe({
        listener.onSuccess(it)
    }, {
        listener.onFailure(it)
    })

fun <data> subscribe2(
    observable: Observable<data>,
    listener: SubscribeViewModel<data>
): Disposable = observable.compose(observeOnMain<data>())
    .doOnSubscribe {
        listener.onStart()
    }.doOnError {
        if (it.code == 401) {

        }
    }.subscribe({
        if (it == null) {
            throw CustomException("10000", null)
        } else if (it is List<*>) {
            if (it.size == 0) {
                throw CustomException("10000", null)
            } else {
                listener.onSuccess(it)
            }
        } else {
            listener.onSuccess(it)
        }
    }, { listener.onFailure(it) })